#include "basicitemcommands.h"

#include "../documents/data/graphicdata.h"
#include "../editors/items/graphicitemcommon.h"

#include <QtGui/QGraphicsItem>

using namespace core;
using namespace swp;

ItemMoveCommand::ItemMoveCommand(GraphicData* data, IGraphicEditorItem* item,
    const QPointF& oldPos, const QPointF& newPos) : QUndoCommand(),
        m_data(data),
        m_item(item),
        m_oldPos(oldPos),
        m_newPos(newPos)
{
    setText(QObject::tr("%1 item moved").arg(item->name()));
}

ItemMoveCommand::~ItemMoveCommand()
{

}

void ItemMoveCommand::undo()
{
    QGraphicsItem* _item = dynamic_cast<QGraphicsItem* >(m_item);

    if (_item != 0)
    {
        m_data->setIgnoreSnapFlag(true);
        _item->setPos(m_oldPos);
        m_data->setIgnoreSnapFlag(false);
    }

    m_data->emitDataChanged(); // not ideal
}

void ItemMoveCommand::redo()
{
    QGraphicsItem* _item = dynamic_cast<QGraphicsItem* >(m_item);

    if (_item != 0 && _item->pos() != m_newPos)
    {
        m_data->setIgnoreSnapFlag(true);
        _item->setPos(m_newPos);
        m_data->setIgnoreSnapFlag(false);
    }
}

ItemsMoveCommand::ItemsMoveCommand(GraphicData* data,
    IGraphicEditorItem* pivotItem,
    const QList<IGraphicEditorItem* >& items,
    const QPointF& oldPos, const QPointF& newPos) : QUndoCommand(),
        m_data(data),
        m_pivotItem(pivotItem),
        m_items(items),
        m_oldPos(oldPos),
        m_newPos(newPos)
{
    setText(QObject::tr("Multiple items moved"));
}

ItemsMoveCommand::~ItemsMoveCommand()
{

}

void ItemsMoveCommand::undo()
{
    QGraphicsItem* pivot = dynamic_cast<QGraphicsItem* >(m_pivotItem);

    if (pivot != 0)
    {
        m_data->setIgnoreSnapFlag(true);

        const QPointF dif = m_oldPos - pivot->pos();

        foreach (IGraphicEditorItem* item, m_items)
        {
            QGraphicsItem* _item =
                dynamic_cast<QGraphicsItem* >(item);

            if (_item != 0 && !isLineItem(_item->type()) &&
                !isConnectorItem(_item->type()))
            {
                _item->moveBy(dif.x(), dif.y());
            }
        }

        pivot->setPos(m_oldPos);

        m_data->setIgnoreSnapFlag(false);
    }

    m_data->emitDataChanged(); // not ideal
}

void ItemsMoveCommand::redo()
{
    QGraphicsItem* pivot = dynamic_cast<QGraphicsItem* >(m_pivotItem);

    if (pivot != 0 && pivot->pos() != m_newPos)
    {
        m_data->setIgnoreSnapFlag(true);

        const QPointF dif = m_newPos - m_oldPos;

        foreach (IGraphicEditorItem* item, m_items)
        {
            QGraphicsItem* _item =
                dynamic_cast<QGraphicsItem* >(item);

            if (_item != 0 && !isLineItem(_item->type()) &&
                !isConnectorItem(_item->type()))
            {
                _item->moveBy(dif.x(), dif.y());
            }
        }

        pivot->setPos(m_newPos);

        m_data->setIgnoreSnapFlag(false);
    }
}

AnchorMoveCommand::AnchorMoveCommand(QGraphicsItem* item,
    const QPointF& oldPos, const QPointF& newPos) : QUndoCommand(),
        m_item(item),
        m_oldPos(oldPos),
        m_newPos(newPos)
{
    setText(QObject::tr("Anchor moved"));
}

AnchorMoveCommand::~AnchorMoveCommand()
{

}

void AnchorMoveCommand::undo()
{
    if (m_item != 0)
    {
        m_item->setPos(m_oldPos);
    }
}

void AnchorMoveCommand::redo()
{
    if (m_item != 0 && m_item->pos() != m_newPos)
    {
        m_item->setPos(m_newPos);
    }
}

ConnectPointMoveCommand::ConnectPointMoveCommand(QGraphicsItem* item,
    const QPointF& oldPos, const QPointF& newPos) : QUndoCommand(),
        m_item(item),
        m_oldPos(oldPos),
        m_newPos(newPos)
{
    setText(QObject::tr("Connect point moved"));
}

ConnectPointMoveCommand::~ConnectPointMoveCommand()
{

}

void ConnectPointMoveCommand::undo()
{
    if (m_item != 0)
    {
        m_item->setPos(m_oldPos);
    }
}

void ConnectPointMoveCommand::redo()
{
    if (m_item != 0 && m_item->pos() != m_newPos)
    {
        m_item->setPos(m_newPos);
    }
}

PropertyChangeCommand::PropertyChangeCommand(core::IEditorItem* item,
    const core::Property& property,
    const QVariant& newValue) : QUndoCommand(),
    m_item(item),
    m_propName(property.Name),
    m_newValue(newValue),
    m_oldValue(property.value())
{
    setText(QObject::tr("Property \"%1\" of %2 item changed to \"%3\"").arg(
        property.Text).arg(item->name()).arg(
            newValue.canConvert(QVariant::List) ?
                newValue.toList().first().toString() : newValue.toString()));
}

PropertyChangeCommand::~PropertyChangeCommand()
{

}

void PropertyChangeCommand::undo()
{
    m_item->propertyChanged(m_propName,
        m_oldValue.canConvert(QVariant::List) ? m_oldValue.toList().first() :
            m_oldValue, true);
}

void PropertyChangeCommand::redo()
{
    m_item->propertyChanged(m_propName, m_newValue, true);
}
